Windows EventLog (.evtx) 분석¶
1. 개요¶
Windows EventLog는 ETW(Event Tracing for Windows)를 기반으로 각 Provider가 발생시킨 이벤트를 EventLog 서비스(wevtsvc.dll, svchost.exe -k LocalServiceNetworkRestricted)가 채널 단위 .evtx 파일로 기록하는 구조다.
분석에서 반드시 구분해야 하는 3가지 개념은 다음과 같다.
| 개념 | 설명 | 예 |
|---|---|---|
| Provider | 이벤트를 발생시키는 주체. Event ID의 의미를 결정한다 | Microsoft-Windows-Security-Auditing |
| Channel | 이벤트가 저장되는 논리적 로그. 파일 하나에 대응한다 | Security, Microsoft-Windows-Sysmon/Operational |
| Event ID | Provider 내부에서 이벤트 종류를 구분하는 번호 | 4624, 7045, 4104 |
Event ID는 전역 고유 식별자가 아니다. 반드시
Channel(또는 Provider) + Event ID조합으로 기록하고 해석해야 한다.
1.1. 로그 저장 위치¶
기본 경로는 아래와 같다. 침해사고 대응 시에는 역할(워크스테이션·멤버 서버·도메인 컨트롤러)에 맞춰 우선순위를 정해 수집한다.
C:\Windows\System32\winevt\Logs\*.evtx
파일명의 %4는 채널 이름의 /를 URL 인코딩한 값이다(/ → %4).
예: Microsoft-Windows-Sysmon/Operational → Microsoft-Windows-Sysmon%4Operational.evtx
수집 우선순위 (침해사고 관점)¶
| 우선순위 | 목적 | 최소 수집 대상 |
|---|---|---|
| P0 | 누가·언제·어떻게 들어왔는지 | Security.evtx, Sysmon, PowerShell Operational |
| P1 | 무엇을 실행·설치했는지 | System.evtx, TaskScheduler, WMI-Activity |
| P2 | 어디로 이동·통신했는지 | TerminalServices, WinRM, SMBClient, DNS Client |
| P3 | 흔적 제거·방어 무력화 | Eventlog Operational, Defender, CodeIntegrity, AppLocker |
| P4 | 부가 상관관계 | Application.evtx, BITS, USB(DriverFrameworks) |
P0만 있어도 초기 타임라인은 가능하지만, PowerShell·Sysmon·TaskScheduler·WMI가 없으면 Living-off-the-Land·지속성·스크립트 기반 공격의 재구성이 크게 제한된다.
P0 — 인증·세션·실행 (거의 모든 호스트)¶
| 파일명 | 채널 | 침해 분석에서 확인할 내용 |
|---|---|---|
Security.evtx |
Security | 로그온 성공·실패(4624/4625), Kerberos(4768/4769/4771), NTLM(4776), 특권·프로세스(4672/4688), 계정·그룹 변경(4720~4738), 공유·객체 접근(5140/5145), 로그 삭제(1102), 감사 정책 변경(4719) |
Microsoft-Windows-Sysmon%4Operational.evtx |
Sysmon/Operational | 프로세스(1), 네트워크(3), DLL 로드(7), 원격 스레드(8), LSASS 접근(10), 파일 생성(11), Run 키(13), DNS(22), WMI(19~21). 설치·구성이 되어 있을 때만 존재 |
Microsoft-Windows-PowerShell%4Operational.evtx |
PowerShell/Operational | 스크립트 블록(4104), 모듈 로깅(4103), 의심 Warning 4104. 다운로드 크래들·난독화·원격 실행 재구성 |
Windows PowerShell.evtx |
Windows PowerShell | 엔진 시작·종료(400/403), 파이프라인(500/501). Operational과 함께 봐야 세션 전후가 연결됨 |
P1 — 서비스·지속성·시스템 변경¶
| 파일명 | 채널 | 침해 분석에서 확인할 내용 |
|---|---|---|
System.evtx |
System | 서비스 설치(7045), 서비스 시작·중지(7036), 예기치 않은 종료(6008/41), Event Log 서비스(6005/6006), 드라이버·PnP(219/20001), 재부팅 요청(1074) |
Microsoft-Windows-TaskScheduler%4Operational.evtx |
TaskScheduler/Operational | 작업 등록·변경(106/140/141), 실행(200/201), 작업이 만든 프로세스(129). schtasks·원격 작업 지속성 |
Microsoft-Windows-WMI-Activity%4Operational.evtx |
WMI-Activity/Operational | WMI 공급자 로드(5857), 실패(5858), 영구 이벤트 소비자(5861). WMI 기반 백도어·원격 실행 |
Setup.evtx |
Setup | 패치·기능 설치·업그레이드. 비정상 시간대 대량 변경·실패는 2차 지표 |
P2 — 원격 접속·횡적 이동·네트워크¶
| 파일명 | 채널 | 침해 분석에서 확인할 내용 |
|---|---|---|
Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx |
TerminalServices-RemoteConnectionManager/Operational | RDP 인증 성공(1149), 출발지 IP(Param3) |
Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx |
TerminalServices-LocalSessionManager/Operational | RDP 세션 로그온·셸·연결 해제(21~25) |
Microsoft-Windows-TerminalServices-RDPClient%4Operational.evtx |
TerminalServices-RDPClient/Operational | 이 호스트가 RDP로 접속한 대상 기록(1024/1102). 피해 서버 Security와 방향 구분 필수 |
Microsoft-Windows-WinRM%4Operational.evtx |
WinRM/Operational | WinRM 세션·Shell(91/168 등). PS Remoting·원격 관리 남용 |
Microsoft-Windows-SMBClient%4Security.evtx |
SMBClient/Security | SMB 클라이언트 인증 실패(31001). 공유·IPC$·자격 증명 시도 |
Microsoft-Windows-SMBClient%4Connectivity.evtx |
SMBClient/Connectivity | SMB 연결 성공·실패. PsExec·관리 공유 접근 상관 |
Microsoft-Windows-DNS-Client%4Operational.evtx |
DNS-Client/Operational | 클라이언트 DNS 질의(3008 등). C2 도메인·이상 FQDN (Sysmon 22와 교차) |
Microsoft-Windows-Firewall%4Firewall.evtx |
Windows Firewall With Advanced Security/Firewall | 연결 허용·차단(5152/5156/5157), 규칙 변경(4946~4948). 방화벽 무력화·포트 개방 |
P3 — 탐지·무결성·로그 조작¶
| 파일명 | 채널 | 침해 분석에서 확인할 내용 |
|---|---|---|
Microsoft-Windows-Eventlog%4Operational.evtx |
Eventlog/Operational | Security 외 채널 로그 삭제(104), 채널 설정 변경. 1102와 함께 은폐 시도 확인 |
Microsoft-Windows-Windows Defender%4Operational.evtx |
Windows Defender/Operational | 탐지·조치(1116/1117), 실시간 보호 끔(5001), 정책 변경(5007) |
Microsoft-Windows-Windows Defender%4WHC.evtx |
Windows Defender/WHC | 제어된 폴더 접근 등 (환경에 따라) |
Microsoft-Windows-CodeIntegrity%4Operational.evtx |
CodeIntegrity/Operational | 서명·정책 위반(3033/3077). 드라이버·DLL 무결성 (Security 5038/6281과 교차) |
Microsoft-Windows-AppLocker%4EXE and DLL.evtx |
AppLocker/EXE and DLL | 정책 위반·차단(8003/8004). 실행 통제 우회 시도 |
Microsoft-Windows-AppLocker%4MSI and Script.evtx |
AppLocker/MSI and Script | 스크립트·MSI 차단 이벤트 |
Microsoft-Windows-SmartScreen%4Debug.evtx |
SmartScreen/Debug | 다운로드·실행 차단 (버전·정책에 따라 채널명 상이할 수 있음) |
P4 — 부가 증거 (다운로드·매체·애플리케이션)¶
| 파일명 | 채널 | 침해 분석에서 확인할 내용 |
|---|---|---|
Microsoft-Windows-Bits-Client%4Operational.evtx |
Bits-Client/Operational | BITS 작업 생성·완료(3/59/60). 백그라운드 파일 다운로드 |
Microsoft-Windows-DriverFrameworks-UserMode%4Operational.evtx |
DriverFrameworks-UserMode/Operational | USB 등 장치 연결·해제(2003/2100/2102). 데이터 유출·악성 도구 투입 |
Application.evtx |
Application | 특정 애플리케이션 오류·설치 로그. IIS·DB·백업 SW 등 서비스 역할에 맞춰 해석 |
Microsoft-Windows-CertificateServicesClient-Lifecycle-System%4Operational.evtx |
CertificateServicesClient-Lifecycle-System/Operational | 인증서 자동 등록·갱신 이상 (AD CS·인증서 남용 조사 시) |
도메인 컨트롤러(DC) — 추가로 우선 수집¶
DC는 워크스테이션 P0~P3에 더해 Kerberos·계정·복제 관련 채널이 중요하다.
| 파일명 | 채널 | 침해 분석에서 확인할 내용 |
|---|---|---|
Security.evtx |
Security | 4768/4769/4771(Kerberos), DCSync 의심(4662 + 특정 Properties), 그룹·계정 대량 변경 |
Microsoft-Windows-Directory-Services-SAM%4Operational.evtx |
Directory-Services-SAM/Operational | SAM·자격 증명 관련 운영 이벤트 (빌드·정책에 따라) |
Microsoft-Windows-ActiveDirectory_DomainService%4Operational.evtx |
ActiveDirectory_DomainService/Operational | AD DS 서비스·복제·구성 이상 |
Microsoft-Windows-DNS-Server%4Audit.evtx |
DNS-Server/Audit | DNS 서버 감사 (존·레코드 변경, 환경에서 Audit 활성화 필요) |
Microsoft-Windows-NTLM%4Operational.evtx |
NTLM/Operational | NTLM 인증 정책·호환 모드 이슈, 레거시 인증 남용 |
역할별 수집 체크리스트 (요약)¶
| 호스트 역할 | 반드시 포함 | 가능하면 포함 |
|---|---|---|
| 일반 PC / VDI | Security, Sysmon, PowerShell×2, TerminalServices×2~3 | TaskScheduler, WMI, Defender, DNS Client |
| 멤버 서버 (파일·앱) | 위 + System, SMBClient, Firewall | AppLocker, CodeIntegrity, Application |
| DC | 위 P0~P3 + DC 표 | DNS-Server Audit, AD DS Operational |
| 공격자가 접속한 클라이언트 | Security, PowerShell, RDPClient Operational | Sysmon, DNS Client |
현장에서 채널·파일 존재 확인¶
모든 .evtx가 기본 활성화되어 있지 않다. 파일이 없거나 RecordCount=0이면 “공격이 없었다”가 아니라 기록되지 않았거나 이미 롤오버된 것일 수 있다.
$logRoot = "$env:SystemRoot\System32\winevt\Logs"
# 침해 대응 우선 채널 (이름 일부 매칭)
$priority = @(
'Security','System','Microsoft-Windows-Sysmon/Operational',
'Microsoft-Windows-PowerShell/Operational','Windows PowerShell',
'Microsoft-Windows-TaskScheduler/Operational',
'Microsoft-Windows-WMI-Activity/Operational',
'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational',
'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational',
'Microsoft-Windows-TerminalServices-RDPClient/Operational',
'Microsoft-Windows-WinRM/Operational',
'Microsoft-Windows-SMBClient/Security',
'Microsoft-Windows-Windows Defender/Operational',
'Microsoft-Windows-Eventlog/Operational',
'Microsoft-Windows-CodeIntegrity/Operational',
'Microsoft-Windows-Bits-Client/Operational'
)
Get-WinEvent -ListLog * -ErrorAction SilentlyContinue |
Where-Object { $_.LogName -in $priority -or $_.LogName -like '*TerminalServices*' } |
Sort-Object LogName |
Select-Object LogName, IsEnabled, RecordCount,
@{n='SizeMB';e={[math]::Round($_.FileSize/1MB,2)}},
@{n='Oldest';e={$_.OldestRecordTime}},
@{n='Newest';e={$_.NewestRecordTime}}
# 실제 파일 목록 (증거 수집용)
Get-ChildItem $logRoot -Filter *.evtx |
Sort-Object Length -Descending |
Select-Object Name, @{n='MB';e={[math]::Round($_.Length/1MB,2)}}, LastWriteTime
증거 보존 시 wevtutil epl로 채널 단위 내보내기를 권장한다. 라이브 파일을 직접 복사하면 Dirty 플래그·누락 레코드 이슈가 생길 수 있다(2장 참고).
$out = 'D:\IR\evtx'
New-Item -ItemType Directory -Force -Path $out | Out-Null
foreach ($name in $priority) {
wevtutil epl $name "$out\$($name -replace '[\\/:*?"<>|]','_').evtx" 2>$null
}
1.2. 채널 설정 레지스트리¶
로그 활성화 여부, 최대 크기, 롤오버 정책은 레지스트리에 있다. 로그가 비어 있거나 기간이 짧을 때 이 값을 먼저 확인한다.
# 최신(채널) 방식
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\<Channel>
Enabled : 0이면 해당 채널 기록 중단 (안티포렌식 지표)
MaxSize : 최대 파일 크기 (바이트)
Retention : 1이면 가득 찰 때 기록 중단, 0이면 오래된 이벤트 덮어쓰기
File : 실제 저장 경로
# 클래식(Security/System/Application)
HKLM\SYSTEM\CurrentControlSet\Services\EventLog\<Log>
1.3. 로깅 확장 설정¶
기본 설정만으로는 침해 분석에 필요한 필드가 기록되지 않는다. 사전에 다음을 활성화해야 한다.
| 대상 | 설정 위치 | 효과 |
|---|---|---|
| 감사 정책 | auditpol /set /subcategory:"Process Creation" /success:enable |
4688 등 상세 감사 기록 |
| 4688 명령줄 | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit\ProcessCreationIncludeCmdLine_Enabled=1 |
4688에 CommandLine 포함 |
| PowerShell 스크립트 블록 | HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging\EnableScriptBlockLogging=1 |
4104에 실제 코드 기록 |
| PowerShell 모듈 | ...\ModuleLogging\EnableModuleLogging=1 |
4103 파이프라인 기록 |
| Sysmon | 설치 및 구성 파일 | 1, 3, 11, 22 등 고해상도 텔레메트리 |
현재 설정 확인:
auditpol /get /category:*
Get-WinEvent -ListLog * | Where-Object RecordCount -gt 0 |
Sort-Object RecordCount -Descending |
Select-Object LogName, RecordCount, FileSize, IsEnabled
2. .evtx 파일 구조¶
.evtx는 단순 텍스트가 아니라 파일 헤더 + 64KB 청크 + 이벤트 레코드 + Binary XML 구조의 바이너리 포맷이다. 구조를 알아야 삭제·변조·누락을 판단할 수 있다.
┌─────────────────────────────────────┐
│ File Header (4096 bytes) │ "ElfFile\x00"
├─────────────────────────────────────┤
│ Chunk 0 (65536 bytes) │ "ElfChnk\x00"
│ ├ Chunk Header (128 bytes) │
│ ├ String Table (64 × 4 bytes) │
│ ├ Template Table (32 × 4 bytes) │
│ └ Event Records │ "\x2A\x2A\x00\x00"
├─────────────────────────────────────┤
│ Chunk 1 ... │
└─────────────────────────────────────┘
2.1. 파일 헤더 (0x1000 바이트)¶
| 오프셋 | 크기 | 필드 | 의미 |
|---|---|---|---|
0x00 |
8 | Magic | ElfFile\x00 |
0x08 |
8 | FirstChunkNumber | 사용 중인 첫 청크 번호 |
0x10 |
8 | LastChunkNumber | 사용 중인 마지막 청크 번호 |
0x18 |
8 | NextRecordIdentifier | 다음에 기록될 레코드 ID |
0x20 |
4 | HeaderSize | 보통 0x80 |
0x24 |
2 | MinorVersion | 1 |
0x26 |
2 | MajorVersion | 3 |
0x28 |
2 | HeaderBlockSize | 4096 |
0x2A |
2 | NumberOfChunks | 청크 개수 |
0x78 |
4 | FileFlags | 0x1 Dirty, 0x2 Full |
0x7C |
4 | Checksum | 헤더 CRC32 |
FileFlags = 0x1 (Dirty): 헤더와 실제 청크 내용이 동기화되지 않은 상태. 비정상 종료 또는 EventLog 서비스 강제 중단, 라이브 시스템에서 복사한 경우 흔히 나타난다.NextRecordIdentifier와 마지막 청크의 실제 레코드 ID가 크게 어긋나면 레코드 제거를 의심한다.
2.2. 청크 헤더 (0x80 바이트)¶
| 오프셋 | 크기 | 필드 | 의미 |
|---|---|---|---|
0x00 |
8 | Magic | ElfChnk\x00 |
0x08 |
8 | FirstEventRecordNumber | 청크 내 첫 레코드 번호 |
0x10 |
8 | LastEventRecordNumber | 청크 내 마지막 레코드 번호 |
0x18 |
8 | FirstEventRecordIdentifier | 첫 레코드 ID |
0x20 |
8 | LastEventRecordIdentifier | 마지막 레코드 ID |
0x2C |
4 | LastEventRecordDataOffset | 마지막 레코드 오프셋 |
0x30 |
4 | FreeSpaceOffset | 미사용 영역 시작 |
0x34 |
4 | EventRecordsChecksum | 레코드 영역 CRC32 |
0x7C |
4 | Checksum | 청크 헤더 CRC32 |
청크는 한 번 할당되면 64KB로 고정되며, 로그가 롤오버될 때 청크 단위로 재사용된다. 이 때문에 FreeSpaceOffset 이후 슬랙 영역에 이전 레코드의 잔존 데이터가 남는다. EvtxECmd의 HiddenRecord, ExtraDataOffset 판정이 이 영역을 근거로 한다.
2.3. 이벤트 레코드¶
| 오프셋 | 크기 | 필드 | 의미 |
|---|---|---|---|
0x00 |
4 | Magic | 0x2A2A0000 (**\x00\x00) |
0x04 |
4 | Size | 레코드 전체 크기 |
0x08 |
8 | EventRecordIdentifier | 로그 전체에서 증가하는 고유 번호 |
0x10 |
8 | WrittenTime | FILETIME (UTC, 100ns 단위) |
0x18 |
n | BinaryXml | 이벤트 본문 |
| 끝 | 4 | Size (복사) | 레코드 크기 재기록 |
- 시작
Size와 끝Size가 다르면 레코드가 변조되었을 가능성이 높다. EventRecordIdentifier는 증가만 하므로 연속 번호에 공백이 있으면 레코드 삭제, 로그 롤오버, 또는 이벤트 유실(1101/4612)을 검토한다.
FILETIME 수동 변환:
[datetime]::FromFileTimeUtc(133500000000000000)
2.4. Binary XML과 템플릿¶
이벤트 본문은 XML 문자열이 아니라 토큰화된 Binary XML이다. 반복되는 구조는 청크의 Template Table에 한 번만 저장되고, 개별 레코드는 템플릿 참조 + 치환 배열(Substitution Array)만 갖는다.
이 설계가 분석에 주는 영향은 다음과 같다.
- 값은 문자열이 아닌 타입(
UInt32,SID,FILETIME,HexInt64)으로 저장되므로 파서에 따라 표현이 달라진다. 특히ProcessId는 원본이 16진수 문자열인 경우가 많다. - 템플릿이 손상되면 해당 청크의 다수 레코드가 한꺼번에 파싱 실패한다.
- 최종 사용자에게 보이는
Message문장은 파일에 저장되지 않는다. Provider의 리소스 DLL로 렌더링한 결과이므로, 파일만 다른 장비로 옮기면 메시지가 비거나 다르게 보일 수 있다.
2.5. 원본·XML·CSV의 역할 구분¶
| 형식 | 용도 | 한계 |
|---|---|---|
| EVTX | 증거 원본 보존, 구조·무결성 분석, 슬랙 복구 | 사람이 직접 읽기 어렵고 대량 검색 불편 |
| XML | 개별 이벤트의 정확한 필드 검증 | 오프셋·청크 구조와 손상 레코드는 보존되지 않음 |
| CSV | 대량 필터링, 정렬, 타임라인, 빈도 분석 | 고정 스키마와 Map 때문에 필드가 축약·누락될 수 있음 |
| JSON | 자동화, 전체 필드 처리 | Provider 렌더링 메시지와는 별개 |
EVTX는 증거 원본, CSV는 선별·타임라인, XML은 상세 검증에 사용한다. 원본 EVTX는 SHA-256 해시를 기록해 보존하고 폐기하지 않는다.
3. 이벤트 레코드 스키마¶
모든 이벤트는 공통 <System> 영역과 이벤트별 <EventData>(또는 <UserData>) 영역으로 구성된다.
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Security-Auditing"
Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
<EventID>4624</EventID>
<Version>2</Version>
<Level>0</Level>
<Task>12544</Task>
<Opcode>0</Opcode>
<Keywords>0x8020000000000000</Keywords>
<TimeCreated SystemTime="2026-09-19T03:14:07.1234567Z" />
<EventRecordID>184512</EventRecordID>
<Correlation ActivityID="{...}" />
<Execution ProcessID="712" ThreadID="4820" />
<Channel>Security</Channel>
<Computer>WIN-DC01.corp.local</Computer>
<Security />
</System>
<EventData>
<Data Name="SubjectUserSid">S-1-5-18</Data>
<Data Name="TargetUserName">Administrator</Data>
<Data Name="TargetLogonId">0x3e7a91</Data>
<Data Name="LogonType">10</Data>
<Data Name="IpAddress">192.168.10.55</Data>
<Data Name="ProcessName">C:\Windows\System32\svchost.exe</Data>
</EventData>
</Event>
3.1. <System> 필드 의미¶
| 필드 | 의미 | 분석 활용 |
|---|---|---|
Provider Name / Guid |
이벤트 발생 주체 | Event ID 의미 확정의 1차 기준 |
EventID |
이벤트 종류 | Provider 범위 안에서만 유일 |
Version |
이벤트 스키마 버전 | OS 버전에 따라 EventData 필드가 추가·변경됨 |
Level |
심각도 | Security 채널은 대부분 0 |
Task |
범주(Task Category) | 감사 하위 범주 식별 |
Opcode |
동작 단계 | 1 Start, 2 Stop 등 |
Keywords |
비트 플래그 | Security는 성공·실패 구분에 사용 |
TimeCreated SystemTime |
이벤트 생성 시각 | 항상 UTC. 한국 시간은 +9 |
EventRecordID |
파일 내 순번 | 삭제·누락·순서 역전 탐지 |
Correlation ActivityID |
동일 작업 묶음 ID | 같은 작업의 여러 이벤트 연결 |
Execution ProcessID / ThreadID |
이벤트를 기록한 프로세스 | 행위 주체 프로세스와 다름 |
Channel |
저장 채널 | Event ID 의미 확정의 2차 기준 |
Computer |
기록된 호스트 | 다른 호스트의 LogonId·PID와 연결 금지 |
Security UserID |
이벤트를 기록한 계정 SID | 비어 있는 경우 많음 |
Execution ProcessID와 EventData의 ProcessId를 혼동하지 않아야 한다. 전자는 svchost.exe(LSASS/EventLog) 같은 기록 주체이고, 후자가 실제 행위 프로세스다.
3.2. Level 값¶
| 값 | 이름 | 의미 |
|---|---|---|
| 0 | LogAlways | 항상 기록. Security 채널 기본값 |
| 1 | Critical | 치명적 |
| 2 | Error | 오류 |
| 3 | Warning | 경고 |
| 4 | Information | 정보 |
| 5 | Verbose | 상세 |
3.3. Keywords 값 (Security 채널)¶
| 값 | 의미 |
|---|---|
0x8020000000000000 |
Audit Success |
0x8010000000000000 |
Audit Failure |
Audit Success는 "감사 대상 동작이 성공했다"는 뜻이며 "안전하다"는 뜻이 아니다. 반대로 Audit Failure는 오타·설정 오류로도 대량 발생한다.
4. Event ID의 의미를 확정하는 방법¶
4.1. 같은 번호, 다른 의미¶
| Event ID | Channel / Provider | 의미 |
|---|---|---|
| 1102 | Security / Microsoft-Windows-Eventlog |
감사 로그가 삭제됨 |
| 1102 | Microsoft-Windows-TerminalServices-RDPClient/Operational |
RDP 클라이언트가 원격 서버에 연결 |
| 1 | Microsoft-Windows-Sysmon/Operational |
프로세스 생성 |
| 1 | Microsoft-Windows-Kernel-General |
시스템 시간 변경 |
| 4 | Microsoft-Windows-Sysmon/Operational |
Sysmon 서비스 상태 변경 |
| 4 | Microsoft-Windows-Winlogon |
Winlogon 알림 구독 |
따라서 보고서나 타임라인에는 Security 4624, System 7045, Sysmon 1 형태로 채널을 함께 적는다.
4.2. Provider 매니페스트로 ID 정의 조회¶
Provider는 자신이 발생시킬 수 있는 Event ID와 EventData 필드 이름(템플릿)을 매니페스트로 등록한다. 알 수 없는 Event ID를 만나면 문서 검색 대신 시스템에 직접 질의하는 편이 정확하다.
# 특정 Provider가 정의한 모든 Event ID와 설명
(Get-WinEvent -ListProvider Microsoft-Windows-Security-Auditing).Events |
Select-Object Id, Version, Level, @{n='Desc';e={$_.Description}} |
Where-Object Id -eq 4624 | Format-List
# Provider 목록과 각 Provider가 기록하는 채널
Get-WinEvent -ListProvider * | Select-Object Name, LogLinks
# 매니페스트(이벤트 정의 + 템플릿) 원문 XML
wevtutil gp Microsoft-Windows-Sysmon /ge:true /gm:true
이 방법으로 각 Event ID가 어떤 필드(TargetLogonId, LogonType 등)를 갖고 어떤 타입인지 확인할 수 있어, 필드 이름을 추측하지 않고 연계 키를 정할 수 있다.
5. 이벤트를 연결하는 핵심 키¶
| 연결 키 | 용도 | 주의점 |
|---|---|---|
Computer |
같은 호스트의 이벤트인지 확인 | 호스트가 다르면 LogonId·PID를 직접 연결하면 안 됨 |
Channel, Provider |
Event ID 의미 결정 | Event ID 단독으로 의미를 확정하지 않음 |
TimeCreated |
인접 사건 연결 | 모두 UTC. KST는 +9 |
EventRecordID |
같은 파일 내 전후 순서 확인 | 시간 변경·로그 병합 시 시간 정렬과 함께 확인 |
SubjectLogonId |
행동을 수행한 세션 추적 | 같은 컴퓨터, 같은 부팅 구간에서만 유효 |
TargetLogonId |
생성·종료된 세션 추적 | 4624 ↔ 4634/4647/4672 연결의 기준 |
LogonGuid |
인증 이벤트 간 연결 | 00000000-0000-...이면 연결 키로 사용 불가 |
SID |
계정명이 바뀌어도 동일 계정 식별 | 로컬 SID와 도메인 SID 구분 |
ProcessId |
4688·Sysmon 1과 연결 | 16진수/10진수 변환 필요, 재부팅 후 PID 재사용 |
ProcessGuid |
Sysmon 이벤트 간 프로세스 연결 | Sysmon 채널에서만 사용 가능. PID보다 신뢰도 높음 |
IpAddress, IpPort |
출발지와 세션 구분 | NAT·프록시·VPN 고려. - 또는 ::1은 로컬 |
Correlation ActivityID |
동일 작업 단위 묶기 | Provider가 설정하지 않으면 비어 있음 |
| 파일 경로 + 해시 | 실행 파일·드라이버 추적 | 동일 파일명이라도 전체 경로와 해시 확인 |
5.1. Subject와 Target¶
Subject*: 행동을 요청·수행한 주체Target*: 로그인된 계정, 변경된 계정 등 행동의 대상
예를 들어 4724에서 SubjectUserName=Administrator, TargetUserName=user1이면 Administrator가 user1의 암호를 재설정한 것이다.
5.2. LogonId의 유효 범위¶
LogonId(예: 0x3e7)는 해당 컴퓨터의 해당 부팅 구간 안에서만 유일하다. 재부팅되면 재사용된다. 따라서 Security 4608(감사 시스템 시작) 또는 System 6005를 부팅 경계로 삼아 구간을 나눈 뒤 연결해야 한다.
잘 알려진 고정 LogonId:
| LogonId | 계정 |
|---|---|
0x3e7 |
SYSTEM |
0x3e4 |
NETWORK SERVICE |
0x3e5 |
LOCAL SERVICE |
6. 채널별 주요 Event ID¶
6.1. Security — 로그온·인증¶
| Event ID | 의미 | 주요 필드 | 연계 |
|---|---|---|---|
| 4624 | 로그온 성공 | TargetUserName, TargetLogonId, LogonType, IpAddress, ProcessName, LogonGuid, ElevatedToken |
4625, 4648, 4672, 4688, 4634, 4647 |
| 4625 | 로그온 실패 | TargetUserName, LogonType, IpAddress, Status, SubStatus |
4624, 4740 |
| 4634 | 로그온 세션 종료 | TargetLogonId, LogonType |
4624, 4647 |
| 4647 | 사용자가 로그오프 시작 | TargetLogonId |
4624, 4634 |
| 4648 | 명시적 자격 증명으로 로그온 시도 | SubjectLogonId, TargetUserName, TargetServerName, ProcessName |
4624, 4625, 4688 |
| 4672 | 새 로그온에 특수 권한 할당 | SubjectLogonId, PrivilegeList |
4624, 4673, 4674 |
| 4768 | Kerberos TGT 요청 (AS-REQ) | TargetUserName, PreAuthType, TicketEncryptionType, Status |
4769, 4771 |
| 4769 | Kerberos 서비스 티켓 요청 (TGS-REQ) | ServiceName, TicketOptions, TicketEncryptionType |
4768, 4624 |
| 4771 | Kerberos 사전 인증 실패 | TargetUserName, FailureCode, ClientAddress |
4625, 4740 |
| 4776 | NTLM 자격 증명 검증 | TargetUserName, Workstation, Status |
4624, 4625 |
| 4778 | 세션 재연결 | AccountName, ClientAddress, LogonID |
RDP 24/25 |
| 4779 | 세션 연결 해제 | 동일 | RDP 24 |
| 4800 / 4801 | 워크스테이션 잠금 / 잠금 해제 | TargetLogonId |
4624 LogonType 7 |
6.2. Security — 계정·그룹 관리¶
| Event ID | 의미 | 연계 |
|---|---|---|
| 4720 | 사용자 계정 생성 | 4722, 4724, 4728, 4732, 4738 |
| 4722 | 계정 활성화 | 4720, 4725 |
| 4723 | 사용자가 자신의 암호 변경 시도 | 4724, 4738 |
| 4724 | 다른 계정의 암호 재설정 시도 | 4738(PasswordLastSet 변경) |
| 4725 | 계정 비활성화 | 4722 |
| 4726 | 계정 삭제 | 4720, 4738 |
| 4738 | 사용자 계정 속성 변경 | PasswordLastSet, OldUacValue/NewUacValue, SidHistory |
| 4740 | 계정 잠금 | 4625, 4771 다수 선행 |
| 4767 | 계정 잠금 해제 | 4740 |
| 4781 | 계정 이름 변경 | 4738 |
| 4728 / 4729 | 전역 보안 그룹 구성원 추가 / 제거 | 4720, 4732 |
| 4732 / 4733 | 로컬 보안 그룹 구성원 추가 / 제거 | Administrators 추가는 권한 상승 지표 |
| 4756 / 4757 | 유니버설 그룹 구성원 추가 / 제거 | 도메인 환경 |
6.3. Security — 프로세스·객체·공유¶
| Event ID | 의미 | 분석 포인트 |
|---|---|---|
| 4688 | 프로세스 생성 | NewProcessName, ParentProcessName, CommandLine(설정 필요), TokenElevationType |
| 4689 | 프로세스 종료 | 실행 시간 계산 |
| 4697 | 서비스 설치 | ServiceFileName, ServiceStartType. System 7045와 교차 확인 |
| 4698 / 4699 | 예약 작업 생성 / 삭제 | TaskContent XML 안의 실행 명령 확인 |
| 4700 / 4701 / 4702 | 예약 작업 활성화 / 비활성화 / 변경 | 지속성 |
| 4656 / 4658 / 4660 / 4663 | 객체 핸들 요청 / 종료 / 삭제 / 접근 | SACL 설정 필요. ObjectName, AccessMask |
| 4670 | 객체 권한 변경 | ACL 변조 |
| 4662 | 디렉터리 서비스 객체 작업 | Properties GUID가 1131f6aa-*/1131f6ad-*면 DCSync 의심 |
| 5140 | 네트워크 공유 접근 | ShareName, IpAddress |
| 5145 | 공유 객체 상세 접근 확인 | IPC$+svcctl은 PsExec류 원격 실행 지표 |
| 4673 / 4674 | 특권 서비스 호출 / 특권 객체 작업 | 4672와 연계 |
6.4. Security — 정책·감사·로그 상태¶
| Event ID | 의미 | 분석 포인트 |
|---|---|---|
| 1100 | EventLog 서비스 종료 | 정상 종료면 System 6006과 동반 |
| 1101 | 감사 이벤트 전송 중 손실 | 해당 시간대 로그 불완전 경고 |
| 1102 | 감사 로그 삭제 | SubjectUserName, SubjectLogonId. 강한 은폐 지표 |
| 1108 | 이벤트 처리 중 EventLog 서비스 오류 | 1101과 동반 |
| 4608 | Windows 시작 및 감사 시스템 초기화 | LogonId/PID 유효 구간의 경계 |
| 4612 | 감사 큐 리소스 고갈로 감사 이벤트 손실 | 로그 신뢰성 |
| 4616 | 시스템 시간 변경 | PreviousTime, NewTime, ProcessName. NTP 보정은 정상 |
| 4719 | 시스템 감사 정책 변경 | 감사 무력화 지표 |
| 4904 / 4905 | 보안 이벤트 소스 등록 / 등록 해제 | AuditSourceName, EventSourceId |
| 4906 | CrashOnAuditFail 값 변경 | |
| 4907 | 객체 감사 설정 변경 | |
| 4902 | 사용자별 감사 정책 테이블 생성 | 부팅 직후면 정보성 |
| 5024 / 5025 | 방화벽 서비스 시작 / 중지 | 5025는 방화벽 무력화 검토 |
| 5033 / 5034 | 방화벽 드라이버 시작 / 중지 | |
| 4946 / 4947 / 4948 | 방화벽 규칙 추가 / 변경 / 삭제 | 포트 개방 지표 |
| 5152 / 5154 / 5156 / 5157 | WFP 패킷 차단 / 수신 대기 허용 / 연결 허용 / 연결 차단 | 네트워크 흐름 |
6.5. System¶
| Event ID | Provider | 의미 |
|---|---|---|
| 7045 | Service Control Manager | 새 서비스 설치. ImagePath 확인. PsExec의 PSEXESVC 등 |
| 7034 / 7031 | Service Control Manager | 서비스 비정상 종료 / 예기치 않은 종료 |
| 7036 | Service Control Manager | 서비스 시작·중지 상태 전환 |
| 7040 | Service Control Manager | 서비스 시작 유형 변경(수동→자동 등) |
| 7009 / 7000 | Service Control Manager | 서비스 시작 타임아웃 / 시작 실패 |
| 6005 | EventLog | EventLog 서비스 시작 = 부팅 |
| 6006 | EventLog | EventLog 서비스 정상 종료 = 정상 셧다운 |
| 6008 | EventLog | 예기치 않은 시스템 종료 |
| 6013 | EventLog | 시스템 가동 시간(일 1회) |
| 104 | Microsoft-Windows-Eventlog | 로그 파일 삭제(Security 외 채널) |
| 1074 | User32 | 종료·재부팅 요청. 요청 프로세스와 사용자 기록 |
| 41 | Kernel-Power | 정상 종료 없이 재부팅됨 |
| 219 | Kernel-PnP | 드라이버 로드 |
| 20001 | UserPnp | 장치 설치 (USB 등) |
| 1 | Kernel-General | 시스템 시간 변경 |
6.6. PowerShell¶
| Channel | Event ID | 의미 |
|---|---|---|
Windows PowerShell |
400 / 403 | 엔진 상태 Available / Stopped. HostApplication 확인 |
Windows PowerShell |
500 / 501 | 명령 시작 / 완료 |
Windows PowerShell |
600 | 공급자 수명 주기. WSMan 등장 시 원격 실행 |
PowerShell/Operational |
4103 | 모듈·파이프라인 로깅. 실행 명령과 인자 |
PowerShell/Operational |
4104 | 스크립트 블록 로깅. 실제 코드 원문. Level Warning은 의심 패턴 |
PowerShell/Operational |
4105 / 4106 | 스크립트 블록 시작 / 종료 |
PowerShell/Operational |
40961 / 40962 | 콘솔 시작 |
PowerShell/Operational |
53504 | PowerShell 원격 세션 인증 |
4104는 긴 스크립트를 여러 이벤트로 분할한다. ScriptBlockId, MessageNumber, MessageTotal로 재조립해야 전체 코드를 볼 수 있다.
6.7. Sysmon (Microsoft-Windows-Sysmon/Operational)¶
| Event ID | 의미 | 핵심 필드 |
|---|---|---|
| 1 | 프로세스 생성 | Image, CommandLine, Hashes, ParentImage, ProcessGuid |
| 2 | 파일 생성 시간 변경 | 타임스톰핑 지표 |
| 3 | 네트워크 연결 | SourceIp, DestinationIp, DestinationPort, Image |
| 5 | 프로세스 종료 | ProcessGuid |
| 6 | 드라이버 로드 | 서명 여부. BYOVD 탐지 |
| 7 | 이미지(DLL) 로드 | DLL 사이드로딩 |
| 8 | CreateRemoteThread | 프로세스 인젝션 |
| 9 | RawAccessRead | \\.\C: 직접 읽기. 자격 증명 탈취 |
| 10 | ProcessAccess | lsass.exe 대상 0x1010/0x1410 접근은 덤프 의심 |
| 11 | 파일 생성 | 드롭된 페이로드 |
| 12 / 13 / 14 | 레지스트리 키 생성·삭제 / 값 설정 / 이름 변경 | Run 키 지속성 |
| 15 | FileCreateStreamHash | ADS, Zone.Identifier로 다운로드 출처 확인 |
| 17 / 18 | 명명된 파이프 생성 / 연결 | C2 프레임워크 지표 |
| 19 / 20 / 21 | WMI 이벤트 필터 / 소비자 / 바인딩 | WMI 지속성 |
| 22 | DNS 질의 | QueryName, Image |
| 23 / 26 | 파일 삭제(보관) / 삭제 감지 | 증거 삭제 |
| 25 | 프로세스 변조 | 프로세스 할로잉 |
Sysmon은 ProcessGuid를 제공하므로 PID 재사용 문제 없이 프로세스 트리를 복원할 수 있다. Security 4688과 Sysmon 1을 Image + CommandLine + 시각으로 교차 검증한다.
6.8. TerminalServices (RDP)¶
| Channel | Event ID | 의미 |
|---|---|---|
RemoteConnectionManager/Operational |
1149 | 원격 데스크톱 사용자 인증 성공. Param3가 출발지 IP |
LocalSessionManager/Operational |
21 | RDP 세션 로그온 성공 |
LocalSessionManager/Operational |
22 | 셸 시작 |
LocalSessionManager/Operational |
23 | 로그오프 |
LocalSessionManager/Operational |
24 | 세션 연결 해제 |
LocalSessionManager/Operational |
25 | 세션 재연결 |
RDPClient/Operational |
1024 / 1102 | 접속을 시도한 쪽의 기록. 대상 서버 이름·IP |
Security |
4624 | LogonType=10이면 RDP 대화형 로그온 |
Security 4624/4625는 접근당한 대상 컴퓨터에 기록되고 IpAddress는 출발지다. 반대로 RDPClient/Operational은 접속을 시작한 컴퓨터에 남고 여기 기록된 주소는 접속 대상이다. 방향을 혼동하면 공격 주체와 피해 호스트가 뒤바뀐다.
6.9. 기타 유용한 채널¶
| Channel | Event ID | 의미 |
|---|---|---|
TaskScheduler/Operational |
106 / 140 / 141 | 작업 등록 / 변경 / 삭제 |
TaskScheduler/Operational |
200 / 201 | 작업 동작 시작 / 완료. 실제 실행 파일 |
TaskScheduler/Operational |
129 | 작업이 생성한 프로세스 |
WMI-Activity/Operational |
5857 | WMI 공급자 로드 |
WMI-Activity/Operational |
5858 | WMI 작업 실패. ClientMachine, 질의 원문 |
WMI-Activity/Operational |
5860 / 5861 | 임시 / 영구 이벤트 소비자 등록. 지속성 |
Windows Defender/Operational |
1116 / 1117 | 악성코드 탐지 / 조치 |
Windows Defender/Operational |
5001 / 5007 | 실시간 보호 비활성화 / 설정 변경 |
CodeIntegrity/Operational |
3033 / 3077 | 서명 검증 실패 / 정책 차단 |
Security |
5038 / 6281 | 이미지 해시 / 페이지 해시 검증 실패 |
AppLocker/* |
8003 / 8004 | 정책 위반 감사 / 차단 |
Bits-Client/Operational |
3 / 59 / 60 | BITS 작업 생성 / 시작 / 완료. 파일 다운로드 |
WinRM/Operational |
91 / 168 | WinRM 세션 생성. 원격 실행 |
SmbClient/Security |
31001 | SMB 클라이언트 인증 실패 |
DriverFrameworks-UserMode/Operational |
2003 / 2100 / 2102 | USB 장치 연결·해제 |
7. 필드 값 해석 표¶
7.1. 4624 / 4625 LogonType¶
| 값 | 이름 | 의미 |
|---|---|---|
| 0 | System | SYSTEM 계정용 시스템 로그온 |
| 2 | Interactive | 로컬 콘솔 로그온 |
| 3 | Network | 공유 폴더, SMB, WMI 등 네트워크 로그온 |
| 4 | Batch | 예약 작업 등 배치 |
| 5 | Service | 서비스 제어 관리자가 시작한 서비스 |
| 7 | Unlock | 워크스테이션 잠금 해제 |
| 8 | NetworkCleartext | 평문 자격 증명 전달 (IIS 기본 인증 등) |
| 9 | NewCredentials | runas /netonly. 로컬 토큰 유지, 외부 연결용 자격 증명 |
| 10 | RemoteInteractive | RDP / Terminal Services |
| 11 | CachedInteractive | 캐시된 도메인 자격 증명으로 로그온 |
| 12 | CachedRemoteInteractive | 캐시 자격 증명 기반 RDP |
| 13 | CachedUnlock | 캐시 자격 증명 기반 잠금 해제 |
7.2. 4625 Status / SubStatus¶
Status는 일반적인 결과 코드이고, 구체적 실패 원인은 SubStatus에 있다.
| 코드 | 의미 |
|---|---|
0xC000006D |
일반 로그온 실패 (Status에 주로 나타남) |
0xC000006A |
암호 불일치 |
0xC0000064 |
존재하지 않는 사용자 |
0xC000006F |
허용된 시간 외 로그온 |
0xC0000070 |
허용되지 않은 워크스테이션 |
0xC0000071 |
암호 만료 |
0xC0000072 |
계정 비활성화 |
0xC0000193 |
계정 만료 |
0xC0000224 |
암호 변경 필요 |
0xC0000234 |
계정 잠김 |
0xC000015B |
요청한 로그온 유형이 허용되지 않음 |
0xC0000133 |
시간 동기 오류 (Kerberos clock skew) |
패스워드 스프레잉은 0xC000006A가 여러 계정에 소수 회, 브루트포스는 0xC000006A가 한 계정에 다수 회 나타난다. 계정 열거(enumeration)는 0xC0000064의 비율이 높다.
7.3. Kerberos 실패 코드 (4768 / 4771)¶
| 코드 | 의미 |
|---|---|
0x6 |
존재하지 않는 클라이언트 주체 (계정 열거 지표) |
0x7 |
존재하지 않는 서버 주체 |
0x9 |
키 만료 |
0xC |
정책 위반 (워크스테이션·시간 제한) |
0x12 |
계정 비활성화·만료·잠김·철회 |
0x17 |
암호 만료 |
0x18 |
사전 인증 실패 = 암호 불일치 |
0x19 |
추가 사전 인증 필요 |
0x20 |
티켓 만료 |
0x25 |
시간 차이 과다 (clock skew) |
7.4. TicketEncryptionType (4768 / 4769)¶
| 값 | 알고리즘 | 비고 |
|---|---|---|
0x1, 0x3 |
DES | 사용 금지 수준 |
0x11 |
AES128-CTS-HMAC-SHA1-96 | 정상 |
0x12 |
AES256-CTS-HMAC-SHA1-96 | 정상 |
0x17 |
RC4-HMAC | Kerberoasting 지표 |
0x18 |
RC4-HMAC-EXP | 취약 |
0xFFFFFFFF |
미확인 | 실패 이벤트 |
4769에서 ServiceName이 krbtgt가 아니고 TicketEncryptionType=0x17, TicketOptions=0x40810000이면서 한 계정이 짧은 시간에 다수의 SPN 티켓을 요청하면 Kerberoasting을 검토한다. 4768에서 PreAuthType=0이면 AS-REP Roasting 대상 계정이다.
7.5. 기타 자주 쓰는 값¶
| 필드 | 값 | 의미 |
|---|---|---|
ElevatedToken (4624) |
%%1842 / %%1843 |
Yes / No. UAC 상승 여부 |
ImpersonationLevel (4624) |
%%1833 / %%1840 |
Impersonation / Delegation |
TokenElevationType (4688) |
%%1936 / %%1937 / %%1938 |
Default / 명시적 상승 / 필터링됨 |
VirtualAccount (4624) |
%%1843 |
가상 서비스 계정 여부 |
ProcessId |
0x1a4 |
16진수. 10진수 변환 후 다른 로그와 비교 |
%%숫자 형태는 Provider 리소스의 문자열 참조다. Map이 적용되지 않은 파서 출력에서는 원본 값이 그대로 보인다.
8. 이벤트 연계 흐름¶
8.1. 로그온 라이프사이클¶
로그온 실패
4625 ── 같은 계정/IP/LogonType의 반복 실패, Status·SubStatus 확인
└─ 4771 (Kerberos) / 4776 (NTLM) 로 인증 경로 구분
└─ 4740 계정 잠금으로 이어지는지 확인
명시 자격 증명 사용
4648 ── LogonGuid·계정·프로세스·시간 ──> 4624
로그온 성공
4624 ── TargetLogonId ──> 4672 관리자급 특권 할당
├─ LogonId ───────> 4688 해당 세션의 프로세스 생성
├─ LogonId ───────> 4720/4732/4698 계정 생성·그룹 추가·작업 등록
├─ TargetLogonId ─> 4647 사용자가 로그오프 시작
└─ TargetLogonId ─> 4634 세션 완전 종료
4634만 있고 4647이 없으면 서비스·네트워크 세션 종료이거나 비정상 종료다. 네트워크 로그온(LogonType=3)은 4624와 4634가 초 단위로 붙어 나타나는 것이 정상이다.
8.2. RDP 접속¶
공격자 호스트 대상 서버
──────────── ─────────
RDPClient/Operational 1024,1102
│
└──────────────────────────> RemoteConnectionManager 1149 (인증 성공, 출발지 IP)
↓
Security 4624 LogonType=10
↓
Security 4672 (관리자급이면)
↓
LocalSessionManager 21 → 22 (세션 로그온 → 셸 시작)
↓
Security 4688 세션 내 프로세스 실행
↓
LocalSessionManager 24/25, Security 4779/4778
↓
Security 4647 → 4634, LSM 23
8.3. 원격 실행·횡적 이동¶
| 기법 | 남는 이벤트 조합 |
|---|---|
| PsExec 계열 | 4624 (Type 3) → 4672 → 5145 (IPC$, svcctl) → System 7045 (PSEXESVC) → 4688 → 7045 삭제 흔적 |
| 원격 서비스 생성 | 4624 (Type 3) → 4697 + System 7045 → 7036 시작 |
| 예약 작업 원격 등록 | 4624 (Type 3) → 4698 → TaskScheduler 106 → 200/201 → 4688 |
| WMI 원격 실행 | 4624 (Type 3) → WMI-Activity 5857/5858 → 4688 (부모 WmiPrvSE.exe) |
| WinRM / PS Remoting | 4624 (Type 3) → WinRM 91 → PowerShell 53504 → 4104 → 4688 (부모 wsmprovhost.exe) |
| 패스 더 해시 | 4624 (Type 3/9) + LogonProcessName=NtLmSsp + KeyLength=0 + 4776 |
8.4. 지속성 확보¶
4688 / Sysmon 1 실행
├─ 4698, TaskScheduler 106 예약 작업
├─ 4697, System 7045 서비스
├─ Sysmon 13 (Run 키) 레지스트리 자동 실행
├─ Sysmon 19/20/21, WMI 5861 WMI 영구 소비자
└─ 4720 → 4732 계정 생성 후 Administrators 추가
8.5. 흔적 제거¶
4616 시스템 시간 변경 → 이후 이벤트 시간 신뢰도 하락
Sysmon 2 파일 생성 시간 변경 → 타임스톰핑
1102 Security 로그 삭제 → SubjectUserName, SubjectLogonId 로 수행자 특정
104 기타 채널 로그 삭제
1100 + System 6006/7036/7040 → EventLog 서비스 중지
WINEVT\Channels\*\Enabled=0 → 채널 무력화 (Sysmon 13으로 탐지)
4719 감사 정책 변경 → 감사 항목 비활성화
1102와 104는 로그를 지워도 삭제 사실 자체가 새 로그의 첫 레코드로 남는다. 따라서 Security.evtx의 EventRecordID=1 부근이 1102면 로그가 초기화된 시점이다.
9. 분석 도구와 질의¶
9.1. wevtutil¶
wevtutil el # 사용 가능한 채널 목록
wevtutil gl Security # 채널 설정 (최대 크기, 보존 정책, 경로)
wevtutil gli Security # 로그 상태 (레코드 수, 최초/최종 레코드)
wevtutil gp Microsoft-Windows-Sysmon /ge:true /gm:true # Provider 이벤트 정의
# 분석용 사본 내보내기 (원본 잠금 회피)
wevtutil epl Security D:\case\Security.evtx
# 저장된 파일에 직접 질의
wevtutil qe D:\case\Security.evtx /lf:true /f:xml /q:"*[System[EventID=4624]]"
wevtutil gli의 numberOfLogRecords와 oldestRecordNumber를 비교하면 롤오버로 손실된 구간을 추정할 수 있다. wevtutil cl은 로그를 삭제하므로 분석 중에는 절대 사용하지 않는다.
9.2. Get-WinEvent와 XPath¶
-FilterXPath와 -FilterHashtable은 로그 공급자 측에서 필터링하므로, 전체를 읽고 Where-Object로 거르는 방식보다 수십 배 빠르다.
# 해시테이블 필터 (가장 권장)
Get-WinEvent -FilterHashtable @{
Path = 'D:\case\Security.evtx'
Id = 4624, 4625, 4672
StartTime = '2026-09-18 00:00:00'
EndTime = '2026-09-19 00:00:00'
}
# EventData 필드까지 필터링
$xpath = @"
*[System[EventID=4624]]
and
*[EventData[Data[@Name='LogonType']='10']]
"@
Get-WinEvent -Path 'D:\case\Security.evtx' -FilterXPath $xpath
# Level·Keywords 조합
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-PowerShell/Operational'
Id = 4104
Level = 3 # Warning = 의심 스크립트 블록
}
XPath는 Windows EventLog가 지원하는 XPath 1.0 부분 집합이며 표현식 32개 제한이 있다. 조건이 많으면 여러 질의로 분할한다.
9.3. EventData를 필드로 펼치기¶
Get-WinEvent의 기본 출력은 Message 문자열이라 정렬·조인이 불편하다. EventData를 객체로 변환해 사용한다.
function Expand-EventData {
param([Parameter(ValueFromPipeline)]$Event)
process {
$xml = [xml]$Event.ToXml()
$data = @{}
$xml.Event.EventData.Data | ForEach-Object { $data[$_.Name] = $_.'#text' }
[pscustomobject]@{
TimeUtc = $Event.TimeCreated.ToUniversalTime()
RecordId = $Event.RecordId
Channel = $Event.LogName
EventId = $Event.Id
Computer = $Event.MachineName
Subject = $data['SubjectUserName']
SubjectId = $data['SubjectLogonId']
Target = $data['TargetUserName']
TargetId = $data['TargetLogonId']
LogonType = $data['LogonType']
IpAddress = $data['IpAddress']
Process = $data['ProcessName']
Status = $data['Status']
SubStatus = $data['SubStatus']
}
}
}
Get-WinEvent -FilterHashtable @{Path='D:\case\Security.evtx'; Id=4624} |
Expand-EventData |
Where-Object LogonType -in 3,10 |
Sort-Object TimeUtc |
Export-Csv .\logon.csv -NoTypeInformation -Encoding UTF8
TargetLogonId로 세션 수명을 계산하는 예:
$ev = Get-WinEvent -FilterHashtable @{Path='D:\case\Security.evtx'; Id=4624,4634} |
Expand-EventData
$ev | Group-Object TargetId | ForEach-Object {
$on = ($_.Group | Where-Object EventId -eq 4624).TimeUtc
$off = ($_.Group | Where-Object EventId -eq 4634).TimeUtc
if ($on -and $off) {
[pscustomobject]@{
LogonId = $_.Name
User = ($_.Group | Where-Object EventId -eq 4624).Target
Logon = $on
Logoff = $off
Duration = $off - $on
}
}
}
9.4. EvtxECmd¶
CSV·XML·JSON 변환과 Map 기반 필드 정규화에 사용한다. Map은 각 Event ID의 EventData를 MapDescription, UserName, RemoteHost, PayloadData1~6으로 뽑아 주는 정의 파일이다.
# 0. Map 최신화 (필수). 안 하면 주요 컬럼이 비어 있다
.\EvtxECmd.exe --sync
# 1. 단일 파일 → CSV
.\EvtxECmd.exe -f "D:\case\Security.evtx" --csv "D:\out" --csvf "Security.csv"
# 2. 디렉터리 일괄 처리 (모든 채널 통합 타임라인)
.\EvtxECmd.exe -d "D:\case\winevt\Logs" --csv "D:\out" --csvf "all-events.csv"
# 3. 특정 ID만 포함 / 제외
.\EvtxECmd.exe -f "D:\case\Security.evtx" --csv "D:\out" --inc 4624,4625,4648,4672,4688
.\EvtxECmd.exe -f "D:\case\Security.evtx" --csv "D:\out" --exc 5058,5061,5056
# 4. 상세 검증용 XML
.\EvtxECmd.exe -f "D:\case\Security.evtx" --xml "D:\out" --xmlf "Security.xml"
# 5. 전체 필드 JSON (자동화용)
.\EvtxECmd.exe -f "D:\case\Security.evtx" --json "D:\out" --jsonf "Security.json" --fj
# 6. 볼륨 섀도 카피 포함 (삭제된 로그 복구 가능성)
.\EvtxECmd.exe -d "C:\Windows\System32\winevt\Logs" --csv "D:\out" --vss
출력 CSV에서 특히 볼 컬럼:
| 컬럼 | 의미 |
|---|---|
TimeCreated |
UTC 기준 시각 |
MapDescription |
Map이 부여한 사람이 읽을 수 있는 설명 |
UserName, RemoteHost |
Map이 추출한 계정·원격 호스트 |
PayloadData1~6 |
Map이 지정한 핵심 필드 |
ChunkNumber, RecordNumber |
파일 내 물리적 위치. 삭제·은닉 판단 근거 |
HiddenRecord |
슬랙 영역에서 복구한 레코드 여부 |
ExtraDataOffset |
정상 레코드 범위 밖 데이터 존재 |
Payload |
파싱 전 원본 필드 전체 |
HiddenRecord=True인 레코드는 정상 인덱스에 없지만 청크 슬랙에 남아 있던 이벤트다. 로그 삭제·변조 정황에서 결정적 증거가 될 수 있다.
9.5. 기타 도구¶
| 도구 | 용도 |
|---|---|
evtx_dump |
Rust 기반 고속 XML/JSON 덤프. 손상 파일에도 비교적 강함 |
python-evtx |
스크립트 기반 파싱 및 커스텀 추출 |
Chainsaw |
Sigma 룰 기반 헌팅. chainsaw hunt ./Logs -s ./sigma --mapping ./mappings/sigma-event-logs-all.yml |
Hayabusa |
탐지 룰 내장 타임라인 생성. hayabusa csv-timeline -d ./Logs -o timeline.csv |
Zircolite |
Sigma를 SQLite로 변환해 대량 EVTX에 적용 |
DeepBlueCLI |
PowerShell 기반 빠른 이상 징후 스크리닝 |
Timeline Explorer |
EvtxECmd CSV를 조건·색상 필터로 탐색 |
Event Log Explorer |
GUI 기반 다중 채널 병합 조회 |
10. 로그 신뢰성 검증과 안티포렌식 탐지¶
이벤트가 없다는 사실을 "행위가 없었다"는 증거로 쓰기 전에 다음을 확인한다.
10.1. 커버리지 확인¶
# 로그가 포함하는 실제 기간
$e = Get-WinEvent -Path .\Security.evtx -Oldest -MaxEvents 1
$l = Get-WinEvent -Path .\Security.evtx -MaxEvents 1
"{0} ~ {1}" -f $e.TimeCreated, $l.TimeCreated
# 시간대별 이벤트 밀도로 공백 구간 찾기
Get-WinEvent -Path .\Security.evtx |
Group-Object { $_.TimeCreated.ToString('yyyy-MM-dd HH') } |
Select-Object Name, Count | Sort-Object Name
기간이 사건 시점을 포함하지 않으면 롤오버로 이미 덮여 쓰인 것이다. MaxSize 설정과 이벤트 발생률을 근거로 보존 기간을 추정한다.
10.2. 구조적 변조 지표¶
| 지표 | 확인 방법 | 해석 |
|---|---|---|
FileFlags = Dirty(0x1) |
파일 헤더 0x78 |
비정상 종료 또는 서비스 강제 중단 |
헤더 NextRecordIdentifier와 실제 마지막 레코드 ID 불일치 |
헤더 vs 청크 헤더 | 레코드 제거 의심 |
EventRecordID 연속성 공백 |
정렬 후 차분 | 삭제, 유실(1101/4612), 또는 롤오버 |
레코드 시작·끝 Size 불일치 |
바이너리 확인 | 개별 레코드 변조 |
| 청크 CRC32 불일치 | 파서 경고 | 수동 편집 흔적 |
HiddenRecord 다수 |
EvtxECmd CSV | 슬랙에만 남은 이벤트 존재 |
| 시간 역행 | TimeCreated vs EventRecordID 정렬 비교 |
4616 시간 변경 또는 병합된 로그 |
EventRecordID 공백 확인:
$ids = (Get-WinEvent -Path .\Security.evtx -Oldest).RecordId | Sort-Object
$ids | ForEach-Object -Begin { $p = $null } -Process {
if ($p -and ($_ - $p) -gt 1) { "공백: $($p+1) ~ $($_-1) ($($_-$p-1)개)" }
$p = $_
}
10.3. 삭제·무력화 흔적¶
Security 1102,System 104: 로그 삭제. 수행 계정과 LogonId가 포함되므로 4624와 연결해 주체를 특정한다.Security 1100+System 6006이 정상 셧다운과 함께가 아니면 EventLog 서비스 중지 시도를 검토한다.WINEVT\Channels\<Channel>\Enabled값 변경은 Sysmon 13(레지스트리 값 설정)으로 포착된다.Security 4719(감사 정책 변경)가 사건 직전에 있으면 이후 구간의 감사 항목이 축소되었을 수 있다.Security 1101,4612가 있으면 해당 시간대는 애초에 불완전한 로그다.
10.4. 보조 증거원¶
EVTX가 신뢰할 수 없거나 삭제된 경우 다음을 병행한다.
| 증거원 | 확인 가능한 내용 |
|---|---|
| Volume Shadow Copy | 삭제 이전 시점의 .evtx 원본 |
$MFT, $LogFile, $UsnJrnl |
.evtx 파일 자체의 변경·삭제 시각 |
| Prefetch, Amcache, SRUM, ShimCache | 실행 이력 |
레지스트리(SYSTEM, SOFTWARE, NTUSER.DAT) |
서비스, 자동 실행, 채널 설정 |
| 미할당 영역 카빙 | ElfChnk\x00, 0x2A2A0000 시그니처로 레코드 복구 |
11. 분석 절차¶
1단계: 원본 보존 및 해시¶
Copy-Item C:\Windows\System32\winevt\Logs\*.evtx D:\case\ -Force
Get-ChildItem D:\case\*.evtx | Get-FileHash -Algorithm SHA256 |
Export-Csv D:\case\hashes.csv -NoTypeInformation
라이브 시스템에서는 wevtutil epl로 내보낸 사본을 사용한다. 원본 파일은 수정하지 않는다.
2단계: 커버리지와 신뢰성 확인¶
- 각 채널의 최초·최종 레코드 시각
1102,104,1100,1101,4616,4719존재 여부EventRecordID공백,HiddenRecord
3단계: 통합 타임라인 생성¶
.\EvtxECmd.exe --sync
.\EvtxECmd.exe -d "D:\case" --csv "D:\out" --csvf "timeline.csv"
모든 채널을 UTC 기준 단일 타임라인으로 합친다. 단일 채널만 보면 인증(Security)과 실행(Sysmon), 서비스(System)의 인과 관계를 놓친다.
4단계: 앵커 이벤트 선별¶
침해 시점을 특정할 수 있는 이벤트부터 좁힌다.
- 외부 접근:
4624 LogonType 3/10,1149,4625폭주 - 권한 상승:
4672,4732,4720 - 실행:
4688,Sysmon 1,4104 - 지속성:
7045,4697,4698,WMI 5861 - 은폐:
1102,104,4616,4719
5단계: 연계 키로 확장¶
앵커 이벤트에서 TargetLogonId → SubjectLogonId → ProcessId/ProcessGuid → IpAddress 순으로 확장하며 세션 단위 행위를 복원한다. 부팅 경계(4608, System 6005)를 넘어가는 LogonId·PID는 연결하지 않는다.
6단계: 원문 재검증¶
결론에 사용할 이벤트는 CSV가 아니라 XML 또는 원본 EVTX에서 필드를 다시 확인한다. Map 누락이나 컬럼 축약으로 값이 달라질 수 있다.
.\EvtxECmd.exe -f "D:\case\Security.evtx" --xml "D:\out" --xmlf "Security.xml"
12. 분석 시 피해야 할 오판¶
Audit success를 "안전한 이벤트"로,Audit failure를 "침해 확정"으로 해석하지 않는다.- Event ID만으로 의미를 단정하지 않는다. 같은 번호가 Provider마다 다른 의미를 가진다.
4624를 무조건 사람의 로그인으로 보지 않는다.LogonType0·3·5는 시스템·네트워크·서비스 활동이다.4672를 관리자 침해로 단정하지 않는다. SYSTEM·LOCAL SERVICE 서비스 로그온에서 매우 빈번하다.4648존재를 로그온 성공으로 보지 않는다. 자격 증명 사용 시도일 뿐이며 결과는 4624/4625로 확인한다.Execution ProcessID를 행위 프로세스로 오인하지 않는다.EventData의ProcessId/ProcessName과 구분한다.IpAddress를 항상 출발지로 가정하지 않는다. 대상 서버의 4624에서는 출발지지만RDPClient채널에서는 접속 대상이다.- LogonId·PID를 다른 컴퓨터나 다른 부팅 구간과 직접 연결하지 않는다.
- 이벤트 부재를 행위 부재의 증거로 쓰지 않는다. 롤오버, 감사 미설정, 채널 비활성화, 1101 유실을 먼저 배제한다.
- 건수가 많다는 이유만으로 악성으로 판정하지 않는다.
5038,6281,5058,5061등은 정상 환경에서도 대량 발생한다. - XML을 원본 증거로 취급하지 않는다. 원본은 EVTX다.
- 표시된 로컬 시간에 의존하지 않는다. 파일 내부 시각은 UTC이며 도구에 따라 표시 시간대가 다르다.
13. 참고 자료¶
파일 포맷·구조¶
- libevtx: Windows XML Event Log (EVTX) 포맷 명세
- Microsoft: Event Schema
- Microsoft: Windows Event Log 개요
- Microsoft: Consuming Events / XPath 쿼리 제한
도구¶
- EvtxECmd (Eric Zimmerman)
- EvtxECmd Maps 설명
- evtx_dump (omerbenamram)
- Chainsaw
- Hayabusa
- Zircolite
- DeepBlueCLI
- Sysmon 및 구성
- SwiftOnSecurity Sysmon 설정 템플릿
Event ID 레퍼런스¶
- Microsoft: 고급 보안 감사 이벤트 전체 목록
- Microsoft: 4624 계정 로그온 성공
- Microsoft: 4625 계정 로그온 실패
- Microsoft: 4648 명시적 자격 증명 로그온
- Microsoft: 4672 특수 권한 할당
- Microsoft: 4688 프로세스 생성
- Microsoft: 4768 Kerberos TGT 요청
- Microsoft: 4769 Kerberos 서비스 티켓 요청
- Microsoft: 1102 감사 로그 삭제
- Microsoft: PowerShell 로깅 정보
- NSA/공동 권고: Windows Event Logging 권장 구성